import uuid
import unittest
from datetime import datetime, timedelta

from Autotests.BaseTest import BaseManservSOAPTestCase, PartnerAndAccountAutoCreation


@PartnerAndAccountAutoCreation
class Accounts(BaseManservSOAPTestCase):
    def __init__(self, *args, **kwargs):
        BaseManservSOAPTestCase.__init__(self, *args, **kwargs)

    def setUp(self, *args, **kwargs):
        BaseManservSOAPTestCase.setUp(self, *args, **kwargs)
        self._partnerId = self.getPartnerForCaseInfo().id
        self._productId = str(self.manserv.EnumerateProducts(partnerId = self._partnerId).products.productInfo[0].id)
        self._locationId = self.manserv.EnumerateLocations().locationInfo[0].id
        self._accountName = ''
        self._accountPassword = ''
        self._accountId = ''
        self._baseAccount = {
            'partnerId': self._partnerId,
            'productId': self._productId,
            'locationId': self._locationId,
        }
        self._accountStatisticsRequest = {
            'partnerId': self._partnerId,
            'startRecordNumber': 0,
            'recordsCount': -1,
            'columns': {
                'string': ['AN',],
                },
        }


    def test_AddAccount(self):
        count = self._getAccountsCount()
        result = self._createAccount()
        countAfter = self._getAccountsCount()
        self.assertTrue(result.accountId.isnumeric())
        self.assertEqual(count + 1, countAfter)

        self._deleteAccount(result.accountId)

    def test_ChangeAccountPassword(self):
        newPassword = 'password'
        self._createAccount()
        result = self.manserv.ChangeAccountPassword(account = self._accountName,
                                                    oldPassword = self._accountPassword,
                                                    newPassword = newPassword)
        self.assertIsNotNone(result)
        accountInfo = self.manserv.GetAccountInfoById(accountId = self._accountId)
        self.assertEqual(accountInfo.accountInfo.password, newPassword)
        self._deleteAccount(self._accountId)

    def test_EnumerateAccountStatistics(self):
        self._createAccount()
        result = self.manserv.EnumerateAccountStatistics(**self._accountStatisticsRequest)
        self.assertEqual(result.accountStatistics.accountStatisticsInfo[-1].accountId, self._accountId)
        self.assertEqual(result.accountStatistics.accountStatisticsInfo[-1].partnerId, self._partnerId)
        self._deleteAccount(self._accountId)

    def test_EnumerateAccounts(self):
        self._createAccount()
        result = self.manserv.EnumerateAccounts(partnerId = self._partnerId)
        self.assertEqual(result, '')
        self._deleteAccount(self._accountId)

    def test_GetAccountInfo(self):
        self._createAccount()
        result = self.manserv.GetAccountInfo(account = self._accountName, password = self._accountPassword)
        self.assertEqual(result.accountInfo.id, self._accountId)
        self.assertEqual(result.accountInfo.locationId, self._locationId)
        self.assertEqual(result.accountInfo.name, self._accountName)
        self.assertEqual(result.accountInfo.partnerId, self._partnerId)
        self.assertEqual(result.accountInfo.password, self._accountPassword)
        self.assertEqual(result.accountInfo.productId, self._productId)
        self.assertTrue(bool(result.accountInfo.token))
        self.assertTrue(bool(result.accountInfo.creationTime))
        self.assertTrue(bool(result.accountInfo.expirationTime))

        self._deleteAccount(self._accountId)

    def test_GetAccountInfoById(self):
        self._createAccount()
        result = self.manserv.GetAccountInfoById(accountId = self._accountId, includeHomeNodeInfo = False)
        self.assertEqual(result.accountInfo.id, self._accountId)
        self.assertEqual(result.accountInfo.locationId, self._locationId)
        self.assertEqual(result.accountInfo.name, self._accountName)
        self.assertEqual(result.accountInfo.partnerId, self._partnerId)
        self.assertEqual(result.accountInfo.password, self._accountPassword)
        self.assertEqual(result.accountInfo.productId, self._productId)
        self.assertTrue(bool(result.accountInfo.token))
        self.assertTrue(bool(result.accountInfo.creationTime))
        self.assertTrue(bool(result.accountInfo.expirationTime))

        self._deleteAccount(self._accountId)

    def test_ModifyAccount(self):
        creationTime = (datetime.now() - timedelta(days=1)).isoformat()
        expirationTime = (datetime.now() + timedelta(weeks=3)).isoformat()
        partnerName = uuid.uuid4()
        newPartnerId = self.executor.addPartner(parentInfo = self.executor.getPartnerInfo(self._parentPartner),
                                              name = partnerName,
                                              level = self._partnerLevel)
        newProductId = self.executor.addProduct('newProduct', newPartnerId)
        self._createAccount()
        accountInfoBefore = self.manserv.GetAccountInfoById(accountId = self._accountId)

        newAccount = {
            'name': self._accountName,
            'password': self._accountPassword,
            'partnerId': newPartnerId,
            'productId': newProductId,
            'expectedBackupSize': '1024',
            'creationTime': creationTime,
            'expirationTime': expirationTime,
            'forceRemoveCustomColumnValuesInOldScope': True,
        }

        result = self.manserv.ModifyAccount(**newAccount)
        self.assertIsNone(result)
        accountInfo = self.manserv.GetAccountInfoById(accountId = self._accountId)
        self.assertEqual(accountInfo.accountInfo.expectedBackupSize, newAccount['expectedBackupSize'])
        self.assertEqual(accountInfo.accountInfo.id, self._accountId)
        self.assertEqual(accountInfo.accountInfo.locationId, self._locationId)
        self.assertEqual(accountInfo.accountInfo.name, newAccount['name'])
        self.assertEqual(accountInfo.accountInfo.partnerId, newAccount['partnerId'])
        self.assertEqual(accountInfo.accountInfo.password, newAccount['password'])
        self.assertEqual(accountInfo.accountInfo.productId, newAccount['productId'])
        self.assertEqual(accountInfo.accountInfo.token, accountInfoBefore.accountInfo.token)
        self.assertEqual(accountInfo.accountInfo.creationTime, accountInfoBefore.accountInfo.creationTime)
        self.assertNotEqual(accountInfo.accountInfo.expirationTime, accountInfoBefore.accountInfo.expirationTime)

        self._deleteAccount(self._accountId)
        self.executor.removeProduct(newProductId)
        self.executor.removePartner(partnerName, True)

    def test_ModifyAccountById(self):
        creationTime = (datetime.now() - timedelta(days=1)).isoformat()
        expirationTime = (datetime.now() + timedelta(weeks=3)).isoformat()
        partnerName = uuid.uuid4()
        newPartnerId = self.executor.addPartner(parentInfo = self.executor.getPartnerInfo(self._parentPartner),
                                              name = partnerName,
                                              level = self._partnerLevel)
        newProductId = self.executor.addProduct('newProduct', newPartnerId)
        self._createAccount()
        newAccount = {
            'name': self._accountName,
            'password': self._accountPassword,
            'id': self._accountId,
            'partnerId': newPartnerId,
            'productId': newProductId,
            'creationTime': creationTime,
            'expirationTime': expirationTime,
            'expectedBackupSize': '1024',
            'forceRemoveCustomColumnValuesInOldScope': True,
        }

        accountInfoBefore = self.manserv.GetAccountInfoById(accountId = self._accountId)

        result = self.manserv.ModifyAccountById(**newAccount)
        self.assertIsNone(result)
        accountInfo = self.manserv.GetAccountInfoById(accountId = self._accountId)
        self.assertEqual(accountInfo.accountInfo.expectedBackupSize, newAccount['expectedBackupSize'])
        self.assertEqual(accountInfo.accountInfo.id, self._accountId)
        self.assertEqual(accountInfo.accountInfo.locationId, self._locationId)
        self.assertEqual(accountInfo.accountInfo.name, newAccount['name'])
        self.assertEqual(accountInfo.accountInfo.partnerId, newAccount['partnerId'])
        self.assertEqual(accountInfo.accountInfo.password, newAccount['password'])
        self.assertEqual(accountInfo.accountInfo.productId, newAccount['productId'])
        self.assertEqual(accountInfo.accountInfo.token, accountInfoBefore.accountInfo.token)
        self.assertNotEqual(accountInfo.accountInfo.creationTime, accountInfoBefore.accountInfo.creationTime)
        self.assertNotEqual(accountInfo.accountInfo.expirationTime, accountInfoBefore.accountInfo.expirationTime)

        self._deleteAccount(self._accountId)
        self.executor.removeProduct(newProductId)
        self.executor.removePartner(partnerName, True)

    def test_RemoveAccount(self):
        self._createAccount()
        count = self._getAccountsCount()
        result = self.manserv.RemoveAccount(name = self._accountName, password = self._accountPassword)
        self.assertIsNone(result)
        countAfter = self._getAccountsCount()
        self.assertEqual(count - 1, countAfter)

    def test_RemoveAccountById(self):
        self._createAccount()
        count = self._getAccountsCount()
        result = self.manserv.RemoveAccountById(accountId = self._accountId)
        self.assertIsNone(result)
        countAfter = self._getAccountsCount()
        self.assertEqual(count - 1, countAfter)

    def test_SetAccountExpirationTimeToUnlimited(self):
        self._baseAccount['expirationTime'] = (datetime.now() + timedelta(weeks=2)).isoformat()
        self._createAccount()
        del self._baseAccount['expirationTime']
        accountInfoBefore = self.manserv.GetAccountInfoById(accountId = self._accountId)

        result = self.manserv.SetAccountExpirationTimeToUnlimited(id = self._accountId)
        self.assertIsNone(result)
        accountInfo = self.manserv.GetAccountInfoById(accountId = self._accountId)
        self.assertNotEqual(accountInfo.accountInfo.expirationTime, accountInfoBefore.accountInfo.expirationTime)

        self._deleteAccount(self._accountId)

#---
    def _createAccount(self):
        result = self.manserv.AddAccount(**self._baseAccount)
        self._accountName = result.name
        self._accountPassword = result.password
        self._accountId = result.accountId
        return result

    def _deleteAccount(self, accountId):
        return self.manserv.RemoveAccountById(accountId = accountId)

    def _getAccountsCount(self):
        result = self.manserv.EnumerateAccountStatistics(**self._accountStatisticsRequest)
        return len(result.accountStatistics.accountStatisticsInfo)

if __name__ == "__main__":
    unittest.main()